/**
 *  Copyright [2022] [https://www.xiaonuo.vip]
 *	Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *	1.请不要删除和修改根目录下的LICENSE文件。
 *	2.请不要删除和修改Snowy源码头部的版权声明。
 *	3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 *	4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 *	5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 *	6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
 import { defineStore } from 'pinia'
 import tool from '@/utils/tool'
 import { cloneDeep } from 'lodash-es'
 import userRoutes from '@/config/route'
 import { searchStore } from '@/store/search'
 import router from '@/router'
 import userCenterApi from '@/api/sys/userCenterApi'
 import whiteList from '@/router/whiteList'
 import routesData from '@/router/systemRouter'

 // findPwd和login路由组件已静态加载，此处不在进行异步加载
 const modules = import.meta.glob([
	 '/src/views/**/**.vue',
	 '!/src/views/auth/findPwd/**.vue',
	 '!/src/views/auth/login/**.vue'
 ])
 export const useMenuStore = defineStore('menuStore', () => {
	 const menuData = ref([])
	 const refreshFlag = ref(false)
	 // 改变刷新标志
	 const changeRefreshFlag = (flag) => {
		 refreshFlag.value = flag
	 }
	 // 加载菜单
	 const loadMenu = () => {
		 // 获取用户菜单
		 const apiMenu = tool.data.get('MENU') || []
		 if (apiMenu.length === 0) {
			 // 创建默认模块，显示默认菜单
			 apiMenu[0] = cloneDeep(userRoutes.module[0])
		 }
		 const childrenApiMenu = apiMenu[0].children
		 apiMenu[0].children = [...(childrenApiMenu ? childrenApiMenu : []), ...userRoutes.menu]
		 let menuRouter = filterAsyncRouter(apiMenu)
		 menuRouter = flatAsyncRoutes(menuRouter)
		 menuData.value = menuRouter
		 // 初始化搜索
		 const search_store = searchStore()
		 search_store.init(menuRouter)
	 }
	 // 过滤异步路由
	 const filterAsyncRouter = (routerMap) => {
		 const accessedRouters = []
		 routerMap.forEach((item) => {
			 item.meta = item.meta ? item.meta : {}
			 // 处理外部链接特殊路由
			 if (item.meta.type === 'iframe') {
				 item.meta.url = item.path
				 item.path = `/${item.name}`
			 }
			 // MAP转路由对象
			 const route = {
				 path: item.path,
				 name: item.name,
				 meta: item.meta,
				 redirect: item.redirect,
				 children: item.children ? filterAsyncRouter(item.children) : null,
				 component: loadComponent(item.component)
			 }
			 accessedRouters.push(route)
		 })
		 return accessedRouters
	 }
	 // 将异步路由扁平化
	 const flatAsyncRoutes = (routes, breadcrumb = []) => {
		 const res = []
		 routes.forEach((route) => {
			 const tmp = { ...route }
			 if (tmp.children) {
				 const childrenBreadcrumb = [...breadcrumb]
				 childrenBreadcrumb.push(route)
				 const tmpRoute = { ...route }
				 tmpRoute.meta.breadcrumb = childrenBreadcrumb
				 delete tmpRoute.children
				 res.push(tmpRoute)
				 const childrenRoutes = flatAsyncRoutes(tmp.children, childrenBreadcrumb)
				 childrenRoutes.map((item) => {
					 res.push(item)
				 })
			 } else {
				 const tmpBreadcrumb = [...breadcrumb]
				 tmpBreadcrumb.push(tmp)
				 tmp.meta.breadcrumb = tmpBreadcrumb
				 res.push(tmp)
			 }
		 })
		 return res
	 }
	 // 动态加载组件
	 const loadComponent = (component) => {
		 if (component) {
			 if (component.includes('/')) {
				 return modules[`/src/views/${component}.vue`]
			 }
			 return modules[`/src/views/${component}/index.vue`]
		 } else {
			 return () => import(/* @vite-ignore */ `/src/layout/other/empty.vue`)
		 }
	 }
	 // 从路由中移除菜单
	 const removeFromRouter = () => {
		 const routes = router.getRoutes()
		 // 遍历所有路由
		 routes.forEach((route) => {
			 // 过滤白名单
			 if (
				 whiteList.filter((e) => e.path === route.path).length > 0 ||
				 routesData.filter((e) => e.path === route.path).length > 0
			 ) {
				 return
			 }
			 if (route.name && route.name !== 'layout') {
				 router.removeRoute(route.name)
			 }
		 })
	 }
	 // 获取用户菜单（通过API重新初始化菜单，用于界面实时响应）
	 const fetchMenu = async () => {
		 const menu = await userCenterApi.userLoginMenu()
		 tool.data.set('MENU', menu)
		 refreshMenu()
	 }
	 // 刷新菜单（非API刷新，用于路由守卫内使用）
	 const refreshMenu = () => {
		 loadMenu()
		 removeFromRouter()
		 addToRouter()
		 changeRefreshFlag(true)
	 }
	 // 通过API刷新菜单（仅在layout的onMounted内使用，浏览器刷新只刷新一次）
	 const refreshApiMenu = () => {
		 userCenterApi.userLoginMenu().then((data) => {
			 tool.data.set('MENU', data)
			 nextTick(() => {
				 refreshMenu()
			 })
		 })
	 }
	 // 将菜单添加到路由
	 const addToRouter = () => {
		 menuData.value.forEach((item) => {
			 router.addRoute('layout', item)
		 })
	 }
	 return { menuData, loadMenu, addToRouter, refreshMenu, changeRefreshFlag, refreshFlag, fetchMenu, refreshApiMenu }
 })
